package cn.edu.zzuli.springcloud.service;

import cn.hutool.core.util.IdUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.ribbon.proxy.annotation.Hystrix;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.concurrent.TimeUnit;

@Service
public class PaymentService {

    //正常访问，肯定ok的方法
    public String paymentInfo_ok(Integer id) {
        return "线程池： " + Thread.currentThread().getName() + "paymentInfo_ok, 哈哈：）  id: " + id;
    }


    //fallbackMethod方法加到可能出错的服务上,再多写一个兜底的方法,只要访问时长超过3s,或服务异常,直接调用我们的兜底方法
    @HystrixCommand(fallbackMethod = "paymentInfo_timeoutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public String paymentInfo_timeOut(Integer id) {
        //如果这里异常的话也会去调用 fallbackMethod
//        int a = 10 / 0;

        //要求3秒，睡眠5秒，报超时异常sleep interrupted，调用 fallbackMethod
        int time = 5;
        try {
            TimeUnit.SECONDS.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池： " + Thread.currentThread().getName() + "paymentInfo_timeOut, ┭┮﹏┭┮：）  id: " + id + "耗时(s):" + time;
    }

    public String paymentInfo_timeoutHandler(Integer id) {
        return "线程池： " + Thread.currentThread().getName() + "系统报错或者繁忙, (╯‵□′)╯︵┻━┻：）  id: " + id;
    }

    //======以下是服务熔断
    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
            //如果10次请求中有60%的请求都错误。
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//请求次数
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),//失败率
            //那么开启熔断，并且在10秒后（从开启开始计时）开始尝试恢复
            //进入到 半开(HALF-OPEN)的状态，如果请求失败，还是回到开启状态
            //请求通过，关闭熔断。
            //当 处于开启和半开这两个状态时，我们的服务是对当前接口是拒绝接收请求的。只有关闭后才会放行
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000")//时间窗口期
    })
    public String paymentCircuitBreaker(Integer id) {

        if (id < 0) {
            throw  new RuntimeException("id 不能 < 0");
        }

        String serialNumber = IdUtil.simpleUUID();

        return "线程池： " + Thread.currentThread().getName() + "调用成功，流水号为：" + serialNumber;
    }

    public String paymentCircuitBreaker_fallback(Integer id) {
        return "paymentCircuitBreaker_fallback: id 不能为负数啊，小兄弟你怎么回事？";
    }

}
